package com.lihaozhe.config;

import com.lihaozhe.handler.DefaultAccessDeniedHandler;
import com.lihaozhe.handler.LoginAuthenticationFailureHandler;
import com.lihaozhe.handler.LoginAuthenticationSuccessHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

/**
 * @author 李昊哲
 * @version 1.0
 * 2021/11/28 13:18
 */
@RequiredArgsConstructor
@EnableWebSecurity
public class SerurityConfig extends WebSecurityConfigurerAdapter {
    private final LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler;
    private final LoginAuthenticationFailureHandler loginAuthenticationFailureHandler;
    private final DefaultAccessDeniedHandler defaultAccessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // formLogin 表单提交
        // loginPage 自定义登录页
        // loginProcessingUrl 登陆访问路径：提交表单之后跳转的地址,可以看作一个中转站，这个步骤就是验证user的一个过程
        // successForwardUrl 登录成功后跳转页面 必须是post请求
        // successHandler 登录成功后访问默认请求后端处理器
        // failureForwardUrl 登录失败后跳转页面 必须是post请求
        // failureHandler 登录失败后访问默认请求后端处理器
        // usernameParameter 自定义username
        // passwordParameter 自定义password
        http
                .formLogin()
                .loginPage("/toLoginPage")
                .loginProcessingUrl("/login")
                .successForwardUrl("/toSuccessPage")
                .failureForwardUrl("/toFaieldPage")
                .usernameParameter("account")
                .passwordParameter("authString");

//        http
//                .formLogin()
//                .loginPage("/toLoginPage")
//                .loginProcessingUrl("/login")
//                .successHandler(loginAuthenticationSuccessHandler)
//                .failureHandler(loginAuthenticationFailureHandler)
//                .usernameParameter("account")
//                .passwordParameter("authString");

        // authorizeRequests授权认证
        // anyRequestr任何请求
        // authenticated 必须登录后才能访问
        // antMatchers 规则匹配
        // permitAll 不需要认证允许所有
        // antMatchers 中的页面permitAll允许不需要认证即可访问
        // hasAuthority 某个权限可以可以访问
        // hasAnyAuthority 多个权限可以可以访问
        // hasRole 某个角色可以可以访问
        // hasAnyRole 多个角色可以可以访问
        // 注意Can't configure antMatchers after anyRequest
        // 所有请求必须登录之后才能访问 但忽略/toLoginPage
        // http.authorizeRequests().antMatchers("/toLoginPage").permitAll().anyRequest().authenticated();
        // http.authorizeRequests().antMatchers("/toLoginPage").permitAll().regexMatchers(HttpMethod.GET, "/test/*").permitAll().anyRequest().authenticated();
//        http.authorizeRequests()
//                .antMatchers("/toLoginPage").permitAll()
//                // .antMatchers("/admin/**").hasAuthority("lhz")
//                // .antMatchers("/admin/**").hasAuthority("admin")
//                .antMatchers("/admin/**").hasAnyAuthority("admin", "lhz")
//                // .antMatchers("/admin/**").hasRole("emp")
//                .antMatchers("/admin/**").hasAnyRole("admin", "emp")
//                .antMatchers("/admin/**").hasIpAddress("192.168.18.10")
//                .anyRequest().authenticated();

//        http.authorizeRequests()
//                .antMatchers("/toLoginPage").access("permitAll()")
//                .antMatchers("/admin/**").access("hasAnyAuthority('admin','lhz')")
//                .antMatchers("/admin/**").access("hasAnyRole('admin','emp')")
//                .antMatchers("/admin/**").access("hasIpAddress('192.168.18.102')")
//                .anyRequest().authenticated();

        http.authorizeRequests()
                .antMatchers("/toLoginPage").permitAll()
                .anyRequest().authenticated();

//        http.authorizeRequests()
//                .antMatchers("/toLoginPage").access("permitAll()")
//                .antMatchers("/admin/**").access("hasAnyAuthority('admin','lhz')")
//                .antMatchers("/admin/**").access("hasAnyRole('admin','emp')")
//                .antMatchers("/admin/**").access("hasIpAddress('192.168.18.10')")
//                .anyRequest().access("@accessServiceImpl.hasPermission(request,authentication)");
        // 关闭csrf防护
        // http.csrf().disable();
        // 异常处理
        http.exceptionHandling().accessDeniedHandler(defaultAccessDeniedHandler);
        // 退出登录
        http.logout().logoutUrl("/toLogout").logoutSuccessUrl("/toLoginPage").invalidateHttpSession(true).clearAuthentication(true);
        // 记住我
        // userDetailsService 自定义登录逻辑
        // tokenRepository 持久层对象
        // http.rememberMe();
    }

    @Override
    public void configure(WebSecurity web) {
        String[] permitPaths = {
                "/css/**",
                "/assets/**",
                "/swagger-ui.html",
                "/swagger-resources/**",
                "/webjars/**",
                "/*/api-docs",
                "/druid/**"
        };
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers(permitPaths);
    }

    @Bean
    public PasswordEncoder newPasswordEncoder() {
        // 密码加密解密实现类
        return new BCryptPasswordEncoder();
    }
}